package org.franca.importer.ea.post;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.franca.core.franca.FCompoundType;
import org.franca.core.franca.FEnumerationType;
import org.franca.core.franca.FField;
import org.franca.core.franca.FInterface;
import org.franca.core.franca.FModel;
import org.franca.core.franca.FStructType;
import org.franca.core.franca.FType;
import org.franca.core.franca.FUnionType;
import org.sparx.Attribute; 
import org.sparx.Element;
import org.sparx.Package;

public class ElementRemover extends PostProcessorDecorator {
	
	private static Logger jlog =  Logger.getLogger(ElementRemover.class.getName());

	public ElementRemover(PostProcessor lProcessor) {
		super(lProcessor);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void doConsistencyCheckForStructure(Element eaStruct, FStructType fStruct) {
		
		processor.doConsistencyCheckForStructure(eaStruct, fStruct);
		
		checkAttributeConsistency(eaStruct, fStruct);		
	}

	@Override
	public void doConsistencyCheckForUnion(Element eaUnion, FUnionType fUnion) {
		
		processor.doConsistencyCheckForUnion(eaUnion, fUnion);
		
		checkAttributeConsistency(eaUnion, fUnion);		
	}
	
	private void checkAttributeConsistency(Element element, FCompoundType src) {

		short idx = 0;
		
		for(Attribute a: element.GetAttributes()) {
			
			boolean found = false;
			
			for(FField f: src.getElements()) {
				if(a.GetName().equals(f.getName())) {
					found = true;
					break;
				}
			}
			
			if(!found) {
				jlog.log(Level.WARNING, "Attribute "+a.GetName()+
						" in UML struct "+element.GetName()+" not found in france structure"+
						src.getName());
				element.GetAttributes().Delete(idx);
			}
			
			idx++;

		}
		
	}
	
	@Override
	public void doConsistencyCheckForPackage(Package eaPackage, FModel fModel) {

		short idx = 0;
				
		for(Element e: eaPackage.GetElements()) {
					
			boolean eleFoundinFidl = false;
			
			if(fModel.getTypeCollections().size() > 0) {
				for(FType t: fModel.getTypeCollections().get(0).getTypes()) {
					if(e.GetName().equals(t.getName())) {
						eleFoundinFidl = true;
						break;
					}
				}
			}
			
			if(!eleFoundinFidl) {
				for(FInterface i: fModel.getInterfaces()) {
					if(e.GetName().equals(i.getName())) {
						eleFoundinFidl = true;
						break;
					}					
				}
			}

			if(!eleFoundinFidl) {
				for(FInterface i: fModel.getInterfaces()) {
					for(FType t: i.getTypes()) {
						if(e.GetName().equals(t.getName())) {
							eleFoundinFidl = true;
							break;
						}
					}									
				}
			}

				
			if(!eleFoundinFidl) {
				jlog.log(Level.WARNING, "Type "+e.GetName() +
						" in UML Package "+eaPackage.GetName()+" not found in corresponding franca file");
				eaPackage.GetElements().Delete(idx);
			}
			
			idx++;
		}
	}

	@Override
	public void doConsistencyCheckForEnumeration(Element eaEnum, FEnumerationType fEnum) {
		// TODO Auto-generated method stub
		
	}

}
